package com.thiswhyme.illegalword.core;

import org.springframework.util.StringUtils;

import java.util.*;

/**
 * @description: 敏感词工具类
 * @author: thiswhyme
 * @date: 2021/3/30
 */
public class IllegalWordUtils {

    /**
     * 校验指定字符串中是否包含敏感词
     * @param txt 指定字符串
     * @param matchType 匹配规则
     * @param thesaurus 词库
     * @return
     */
    public static boolean isContainsIllegalWord(String txt, MatchType matchType, Map<String, String> thesaurus) {
        for (int i = 0; i < txt.length(); i++) {
            int matchFlag = checkIllegalWord(txt, i, matchType, thesaurus);
            if (matchFlag > 0) {
                return true;
            }
        }
        return false;
    }

    /**
     * 检查文字中是否包含敏感字符
     * @param txt 指定字符串
     * @param beginIndex 校验起始下标
     * @param matchType 匹配规则
     * @param thesaurus 词库
     * @return 若存在，则返回敏感词字符的长度，不存在返回0
     */
    private static int checkIllegalWord(String txt, int beginIndex, MatchType matchType, Map<String, String> thesaurus) {
        boolean flag = false;
        int matchFlag = 0;
        char word;
        Map nowMap = thesaurus;
        for (int i = beginIndex; i < txt.length(); i++) {
            word = txt.charAt(i);
            nowMap = (Map) nowMap.get(word);
            if (nowMap != null) {
                matchFlag++;
                if (Constants.END_FLAG_VALUE_END.equals(nowMap.get(Constants.END_FLAG_NAME))) {
                    flag = true;
                    //若是最短匹配规则，则直接返回当前结果
                    if (MatchType.MIN.equals(matchType)) {
                        break;
                    }
                }
            } else {
                break;
            }
        }
        if (!flag) {
            matchFlag = 0;
        }
        return matchFlag;
    }

    /**
     * 获取指定字符串中包含的敏感词列表
     * @param txt 指定字符串
     * @param matchType 匹配规则
     * @param thesaurus 词库
     * @return
     */
    public static Set<String> getIllegalWords(String txt, MatchType matchType, Map<String, String> thesaurus) {
        Set<String> sensitiveWordList = new HashSet<String>();

        for (int i = 0; i < txt.length(); i++) {
            int length = checkIllegalWord(txt, i, matchType, thesaurus);
            if (length > 0) {
                sensitiveWordList.add(txt.substring(i, i + length));
                i = i + length - 1;
            }
        }
        return sensitiveWordList;
    }

    /**
     * 替换指定字符串中的敏感词为指定字符
     * @param txt 指定字符串
     * @param matchType 匹配规则
     * @param replaceChar 替换字符，默认*
     * @param thesaurus 词库
     * @return
     */
    public static String replaceIllegalWords(String txt, MatchType matchType, String replaceChar, Map<String, String> thesaurus) {
        String resultTxt = txt;
        Set<String> set = getIllegalWords(txt, matchType, thesaurus);
        Iterator<String> iterator = set.iterator();
        String word;
        String replaceString;
        while (iterator.hasNext()) {
            word = iterator.next();
            replaceString = getReplaceChars(replaceChar, word.length());
            resultTxt = resultTxt.replaceAll(word, replaceString);
        }
        return resultTxt;
    }

    /**
     * 获取替换字符串
     * @param replaceChar 替换字符，默认*
     * @param length 替换长度
     * @return
     */
    private static String getReplaceChars(String replaceChar, int length){
        replaceChar = StringUtils.isEmpty(replaceChar) ? Constants.DEFAULT_REPLACE_CHAR : replaceChar;
        String resultReplace = "";
        for (int i = 0; i < length; i++) {
            resultReplace += replaceChar;
        }
        return resultReplace;
    }
}
